// Widget factory that can be modified for child widgets.
// Copyright 2005 (C) Ralph Thomas

#ifndef MISSION_VIEW_FACTORY_H
#define MISSION_VIEW_FACTORY_H

#include <factory.hpp>
#include <vector>

namespace view {
	//
	/// factory_token_ptr_t is a factory token that uses pointers instead
	/// of references. This is used to store pointers to things and thus
	/// avoid storing references outside the scope they were made in.
	//
	struct factory_token_ptr_t {
		factory_token_ptr_t() : assemblage_m( 0 ), sheet_m( 0 ),
			layout_m( 0 ) {}
		factory_token_ptr_t( const factory_token_ptr_t& rhs )
			: assemblage_m( rhs.assemblage_m ),
			  sheet_m( rhs.sheet_m ), layout_m( rhs.layout_m ) {}

		adobe::assemblage_t*	assemblage_m;
		adobe::sheet_t*		sheet_m;
		adobe::eve_t*		layout_m;
	};
	//
	/// This factory allows widgets to hook factory functions to be used
	/// for children, as well as simply changing the factory token for
	/// children.
	//
	class factory {
	  public:
		//
		/// This structure describes the things that are used by a
		/// factory. This factory_t is what can be customized for
		/// child widgets.
		//
		struct factory_t {
			factory_t( const factory_token_ptr_t& t,
				const adobe::widget_factory_proc_t& f )
				: token( t ), factory( f ) {}
			factory_t( const factory_t& rhs )
				: token( rhs.token ), factory( rhs.factory ) {}

			factory_token_ptr_t		token;
			adobe::widget_factory_proc_t	factory;
		};

		void push( const factory_t& f );
		void pop();
		factory_t top( const adobe::factory_token_t& token ) const;

		adobe::widget_node_t build( adobe::name_t	name,
			const adobe::dictionary_t&		params,
			const adobe::widget_node_t&		parent,
			const adobe::factory_token_t&		token );
	  private:
		typedef std::vector<factory_t>	factory_list_t;
		factory_list_t 			_factories;
	};
};

#endif

